#!/usr/bin/env python3
"""
FlatBuffer Schema to C++ Struct Generator (V2版本)

这个脚本解析FlatBuffer的.fbs文件，生成对应的C++结构体，
以及分离的序列化/反序列化接口函数。

特性:
- 生成纯POD数据结构
- 分离的序列化接口：serialize(const MsgType& data)
- 分离的反序列化接口：deserialize(MsgType& data, const FBType* fb_obj)
- 自动跳过标记为deprecated的字段
- 支持各种FlatBuffer数据类型
"""

import os
import sys
import re
import argparse
from typing import Dict, List, Optional, Tuple, Set
from dataclasses import dataclass
from enum import Enum

class FieldType(Enum):
    BASIC = "basic"
    STRING = "string"
    VECTOR = "vector" 
    ENUM = "enum"
    STRUCT = "struct"
    TABLE = "table"
    UNION = "union"

@dataclass
class Field:
    name: str
    type_name: str
    field_type: FieldType
    default_value: Optional[str] = None
    is_deprecated: bool = False
    is_required: bool = False
    is_key: bool = False
    vector_element_type: Optional[str] = None
    original_type_name: Optional[str] = None  # 保存原始FlatBuffer类型名
    
@dataclass
class EnumDef:
    name: str
    underlying_type: str
    values: List[Tuple[str, int]]

@dataclass
class StructDef:
    name: str
    fields: List[Field]
    is_table: bool = True

@dataclass
class UnionDef:
    name: str
    members: List[str]

@dataclass
class SchemaDef:
    namespace: str
    enums: List[EnumDef]
    structs: List[StructDef]
    unions: List[UnionDef]
    root_type: Optional[str] = None

class FlatBufferSchemaParser:
    """FlatBuffer Schema解析器"""
    
    def __init__(self):
        self.type_mapping = {
            'bool': 'bool',
            'byte': 'int8_t',
            'ubyte': 'uint8_t', 
            'short': 'int16_t',
            'ushort': 'uint16_t',
            'int': 'int32_t',
            'uint': 'uint32_t',
            'float': 'float',
            'long': 'int64_t',
            'ulong': 'uint64_t',
            'double': 'double',
            'int8': 'int8_t',
            'uint8': 'uint8_t',
            'int16': 'int16_t', 
            'uint16': 'uint16_t',
            'int32': 'int32_t',
            'uint32': 'uint32_t',
            'int64': 'int64_t',
            'uint64': 'uint64_t',
        }
        
    def parse_file(self, file_path: str) -> SchemaDef:
        """解析FlatBuffer schema文件"""
        with open(file_path, 'r', encoding='utf-8') as f:
            content = f.read()
        
        # 移除注释
        content = self._remove_comments(content)
        
        schema = SchemaDef(
            namespace="",
            enums=[],
            structs=[],
            unions=[]
        )
        
        # 解析namespace
        schema.namespace = self._parse_namespace(content)
        
        # 解析enums
        schema.enums = self._parse_enums(content)
        
        # 解析structs和tables
        schema.structs = self._parse_structs_and_tables(content)
        
        # 解析unions
        schema.unions = self._parse_unions(content)
        
        # 解析root_type
        schema.root_type = self._parse_root_type(content)
        
        return schema
    
    def _remove_comments(self, content: str) -> str:
        """移除注释"""
        lines = content.split('\n')
        cleaned_lines = []
        for line in lines:
            comment_pos = line.find('//')
            if comment_pos >= 0:
                line = line[:comment_pos]
            cleaned_lines.append(line)
        return '\n'.join(cleaned_lines)
    
    def _parse_namespace(self, content: str) -> str:
        """解析namespace"""
        match = re.search(r'namespace\s+([a-zA-Z_][a-zA-Z0-9_]*(?:\.[a-zA-Z_][a-zA-Z0-9_]*)*)\s*;', content)
        return match.group(1) if match else ""
    
    def _parse_enums(self, content: str) -> List[EnumDef]:
        """解析enum定义"""
        enums = []
        enum_pattern = r'enum\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*:\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*\{([^}]+)\}'
        
        for match in re.finditer(enum_pattern, content):
            enum_name = match.group(1)
            enum_type = match.group(2)
            enum_body = match.group(3)
            
            values = []
            value_pattern = r'([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(-?\d+)'
            for value_match in re.finditer(value_pattern, enum_body):
                values.append((value_match.group(1), int(value_match.group(2))))
            
            enums.append(EnumDef(
                name=enum_name,
                underlying_type=self.type_mapping.get(enum_type, enum_type),
                values=values
            ))
        
        return enums
    
    def _parse_unions(self, content: str) -> List[UnionDef]:
        """解析union定义"""
        unions = []
        union_pattern = r'union\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*\{([^}]+)\}'
        
        for match in re.finditer(union_pattern, content):
            union_name = match.group(1)
            union_body = match.group(2)
            
            # 解析union成员
            members = []
            member_pattern = r'([a-zA-Z_][a-zA-Z0-9_]*)'
            for member_match in re.finditer(member_pattern, union_body):
                member_name = member_match.group(1).strip()
                if member_name and not member_name.endswith(','):
                    members.append(member_name)
            
            unions.append(UnionDef(
                name=union_name,
                members=members
            ))
        
        return unions
    
    def _parse_structs_and_tables(self, content: str) -> List[StructDef]:
        """解析struct和table定义"""
        structs = []
        
        # 获取已知的枚举类型名称
        enums = self._parse_enums(content)
        known_enum_names = {enum.name for enum in enums}
        
        # 获取已知的union类型名称
        unions = self._parse_unions(content)
        known_union_names = {union.name for union in unions}
        
        # 获取已知的表类型名称
        known_table_names = set()
        
        # 首先收集所有表名称
        table_pattern = r'table\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*\{([^}]+)\}'
        for match in re.finditer(table_pattern, content):
            known_table_names.add(match.group(1))
        
        # 解析table
        for match in re.finditer(table_pattern, content):
            struct_name = match.group(1)
            struct_body = match.group(2)
            fields = self._parse_fields(struct_body, known_enum_names, known_table_names, known_union_names)
            
            structs.append(StructDef(
                name=struct_name,
                fields=fields,
                is_table=True
            ))
        
        # 解析struct
        struct_pattern = r'struct\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*\{([^}]+)\}'
        for match in re.finditer(struct_pattern, content):
            struct_name = match.group(1)
            struct_body = match.group(2)
            fields = self._parse_fields(struct_body, known_enum_names, known_table_names, known_union_names)
            
            structs.append(StructDef(
                name=struct_name,
                fields=fields,
                is_table=False
            ))
        
        return structs
    
    def _parse_fields(self, field_body: str, known_enums: Set[str] = None, known_tables: Set[str] = None, known_unions: Set[str] = None) -> List[Field]:
        """解析字段定义"""
        fields = []
        
        # 改进的字段解析模式
        field_pattern = r'([a-zA-Z_][a-zA-Z0-9_]*)\s*:\s*([^;(]+?)(?:\s*\(([^)]*)\))?\s*(?:=\s*([^;]+?))?\s*;'
        
        for match in re.finditer(field_pattern, field_body):
            field_name = match.group(1).strip()
            field_type = match.group(2).strip()
            attributes = match.group(3) if match.group(3) else ""
            default_value = match.group(4).strip() if match.group(4) else None
            
            # 解析属性
            is_deprecated = 'deprecated' in attributes
            is_required = 'required' in attributes
            is_key = 'key' in attributes
            
            # 确定字段类型
            field_type_enum, vector_element_type = self._determine_field_type(field_type, known_enums, known_tables, known_unions)
            
            # 转换类型名
            cpp_type = self._convert_type_name(field_type, vector_element_type, known_tables, known_enums)
            
            fields.append(Field(
                name=field_name,
                type_name=cpp_type,
                field_type=field_type_enum,
                default_value=default_value,
                is_deprecated=is_deprecated,
                is_required=is_required,
                is_key=is_key,
                vector_element_type=vector_element_type,
                original_type_name=field_type if field_type_enum == FieldType.TABLE else None
            ))
        
        return fields
    
    def _determine_field_type(self, type_name: str, known_enums: Set[str] = None, known_tables: Set[str] = None, known_unions: Set[str] = None) -> Tuple[FieldType, Optional[str]]:
        """确定字段类型"""
        type_name = type_name.strip()
        
        if type_name == 'string':
            return FieldType.STRING, None
        elif type_name.startswith('[') and type_name.endswith(']'):
            element_type = type_name[1:-1].strip()
            return FieldType.VECTOR, element_type
        elif type_name in self.type_mapping:
            return FieldType.BASIC, None
        elif known_enums and type_name in known_enums:
            return FieldType.ENUM, None
        elif known_tables and type_name in known_tables:
            return FieldType.TABLE, None
        elif known_unions and type_name in known_unions:
            return FieldType.UNION, None
        else:
            # 假设其他未知类型为结构体
            return FieldType.STRUCT, None
    
    def _convert_type_name(self, type_name: str, vector_element_type: Optional[str] = None, known_tables: Set[str] = None, known_enums: Set[str] = None, namespace: str = "") -> str:
        """转换类型名到C++类型"""
        type_name = type_name.strip()
        
        # 构建命名空间前缀
        namespace_prefix = f"::{namespace}::" if namespace else "::"
        
        if type_name == 'string':
            return 'std::string'
        elif type_name.startswith('[') and type_name.endswith(']'):
            element_type = vector_element_type or type_name[1:-1].strip()
            cpp_element_type = self.type_mapping.get(element_type, element_type)
            if element_type == 'string':
                cpp_element_type = 'std::string'
            elif known_tables and element_type in known_tables:
                # 对于table类型，转换为对应的POD类型
                cpp_element_type = f'{element_type}Msg'
            elif known_enums and element_type in known_enums:
                # 对于枚举类型，使用全局命名空间引用
                cpp_element_type = f'{namespace_prefix}{element_type}'
            elif element_type not in self.type_mapping:
                # 对于未知类型（可能是结构体），使用全局命名空间引用
                cpp_element_type = f'{namespace_prefix}{element_type}'
            return f'std::vector<{cpp_element_type}>'
        elif known_tables and type_name in known_tables:
            # 对于table类型，转换为对应的POD类型
            return f'{type_name}Msg'
        elif known_enums and type_name in known_enums:
            # 对于枚举类型，使用全局命名空间引用
            return f'{namespace_prefix}{type_name}'
        elif type_name in self.type_mapping:
            return self.type_mapping[type_name]
        else:
            # 对于未知类型（可能是结构体），使用全局命名空间引用
            return f'{namespace_prefix}{type_name}'
    
    def _parse_root_type(self, content: str) -> Optional[str]:
        """解析root_type"""
        match = re.search(r'root_type\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*;', content)
        return match.group(1) if match else None

class CppPodStructGenerator:
    """C++ POD结构体代码生成器"""
    
    def __init__(self, schema: SchemaDef):
        self.schema = schema
        # 建立枚举名称到枚举定义的映射
        self.enum_map = {enum.name: enum for enum in schema.enums}
        # 建立表名称到表定义的映射
        self.table_map = {struct.name: struct for struct in schema.structs if struct.is_table}
        # 建立union名称到union定义的映射
        self.union_map = {union.name: union for union in schema.unions}
    
    def generate_header(self, output_file: str):
        """生成完整的C++头文件"""
        
        header_guard = self._generate_header_guard(output_file)
        
        # 从输出文件名推断对应的 generated.h 文件名
        base_name = os.path.basename(output_file).replace('_structs.h', '')
        generated_header = f'"{base_name}_generated.h"'
        
        code = f"""#pragma once

{header_guard}

#include <cstdint>
#include <cstring>
#include <string>
#include <vector>
#include <memory>
#include <flatbuffers/flatbuffers.h>
#include "serializer/flatbuffer_serializer.h"

// 包含FlatBuffer生成的头文件
#include {generated_header}

// namespace flatbuffers {{

"""
        
        # 添加namespace开始
        if self.schema.namespace:
            namespaces = self.schema.namespace.split('.')
            for ns in namespaces:
                code += f"namespace {ns} {{\n"
        
        # 不生成枚举定义，因为FlatBuffer已经生成了
        # 枚举定义由 FlatBuffer 的 flatc 工具生成，避免重复定义
        
        # 生成POD结构体，按依赖顺序排列
        table_structs = [s for s in self.schema.structs if s.is_table]
        sorted_structs = self._sort_structs_by_dependencies(table_structs)
        
        for struct_def in sorted_structs:
            code += self._generate_pod_struct(struct_def)
            code += "\n"
        
        # 添加namespace结束
        if self.schema.namespace:
            namespaces = self.schema.namespace.split('.')
            for ns in reversed(namespaces):
                code += f"}} // namespace {ns}\n"
        
        # 生成序列化接口（在game命名空间外面）
        code += "\n// 序列化接口\n"
        code += "namespace flatbuffers {\n\n"
        
        # 使用相同的依赖排序顺序生成序列化函数
        for struct_def in sorted_structs:
            code += self._generate_serialization_functions(struct_def)
            code += "\n"
        
        code += "} // namespace flatbuffers\n\n"
        
        # code += "} // namespace flatbuffers\n\n"
        
        code += f"#endif // {header_guard.split()[1]}\n"
        
        with open(output_file, 'w', encoding='utf-8') as f:
            f.write(code)
    
    def _sort_structs_by_dependencies(self, structs: List[StructDef]) -> List[StructDef]:
        """按依赖关系排序结构体，被依赖的结构体排在前面"""
        # 创建结构体名称到结构体的映射
        struct_map = {s.name: s for s in structs}
        
        # 计算每个结构体的依赖
        dependencies = {}
        for struct in structs:
            deps = set()
            for field in struct.fields:
                if not field.is_deprecated:
                    # 检查字段类型是否是其他table
                    if field.field_type == FieldType.TABLE and field.type_name.endswith('Msg'):
                        # 移除Msg后缀获取原始表名
                        table_name = field.type_name[:-3]
                        if table_name in struct_map:
                            deps.add(table_name)
                    elif field.field_type == FieldType.VECTOR and field.vector_element_type:
                        # 检查向量元素类型
                        if field.vector_element_type in struct_map:
                            deps.add(field.vector_element_type)
            dependencies[struct.name] = deps
        
        # 拓扑排序
        result = []
        visited = set()
        temp_visited = set()
        
        def visit(struct_name):
            if struct_name in temp_visited:
                # 循环依赖，忽略
                return
            if struct_name in visited:
                return
                
            temp_visited.add(struct_name)
            for dep in dependencies.get(struct_name, set()):
                if dep in struct_map:
                    visit(dep)
            temp_visited.remove(struct_name)
            visited.add(struct_name)
            if struct_name in struct_map:
                result.append(struct_map[struct_name])
        
        for struct in structs:
            if struct.name not in visited:
                visit(struct.name)
        
        return result
    
    def _fix_field_type_namespace(self, type_name: str, field_type: FieldType) -> str:
        """修正字段类型的命名空间引用"""
        if field_type == FieldType.ENUM or field_type == FieldType.STRUCT:
            # 枚举和结构体类型需要全局命名空间引用
            if self.schema.namespace:
                expected_prefix = f"::{self.schema.namespace}::"
                # 如果类型名以 :: 开头但不包含正确的命名空间，修正它
                if type_name.startswith("::") and not type_name.startswith(expected_prefix):
                    # 例如 ::EquipmentType -> ::game::EquipmentType
                    bare_name = type_name[2:]  # 移除 ::
                    return f"{expected_prefix}{bare_name}"
                elif not type_name.startswith("::"):
                    # 例如 EquipmentType -> ::game::EquipmentType
                    return f"{expected_prefix}{type_name}"
        
        return type_name
    
    def _generate_header_guard(self, filename: str) -> str:
        """生成头文件保护宏"""
        base_name = os.path.basename(filename).upper().replace('.', '_').replace('-', '_')
        guard_name = f"GENERATED_{base_name}_H_"
        return f"#ifndef {guard_name}\n#define {guard_name}"
    
    def _generate_enum(self, enum_def: EnumDef) -> str:
        """生成枚举定义"""
        code = f"enum class {enum_def.name} : {enum_def.underlying_type} {{\n"
        
        for value_name, value_num in enum_def.values:
            code += f"    {value_name} = {value_num},\n"
        
        code += "};\n"
        return code
    
    def _generate_pod_struct(self, struct_def: StructDef) -> str:
        """生成POD结构体定义"""
        
        # 过滤掉废弃的字段和Union字段（Union字段需要特殊处理，暂时跳过）
        # 同时也过滤掉包含Union元素的向量
        def should_skip_field(field):
            if field.is_deprecated:
                return True
            if field.field_type == FieldType.UNION:
                return True
            if field.field_type == FieldType.VECTOR and field.vector_element_type:
                # 检查向量元素是否为Union类型
                if field.vector_element_type in self.union_map:
                    return True
            return False
        
        active_fields = [f for f in struct_def.fields if not should_skip_field(f)]
        
        struct_name = f"{struct_def.name}Msg"
        
        # 统计废弃字段和Union字段（包括Union向量）
        deprecated_count = len([f for f in struct_def.fields if f.is_deprecated])
        union_count = len([f for f in struct_def.fields if f.field_type == FieldType.UNION])
        union_vector_count = len([f for f in struct_def.fields if f.field_type == FieldType.VECTOR and f.vector_element_type and f.vector_element_type in self.union_map])
        
        filtered_info = ""
        total_union = union_count + union_vector_count
        if deprecated_count > 0 and total_union > 0:
            filtered_info = f" (已过滤 {deprecated_count} 个废弃字段, {total_union} 个Union相关字段)"
        elif deprecated_count > 0:
            filtered_info = f" (已过滤 {deprecated_count} 个废弃字段)"
        elif total_union > 0:
            filtered_info = f" (已过滤 {total_union} 个Union相关字段)"
        
        code = f"""/**
 * @brief {struct_def.name}的POD数据结构体
 * 对应FlatBuffer Table: {struct_def.name}
 * 自动过滤废弃字段，仅包含 {len(active_fields)} 个活跃字段{filtered_info}
 */
struct {struct_name} {{
"""
        
        # 生成成员变量（纯POD风格，无默认值）
        for field in active_fields:
            comment = self._get_field_comment(field)
            # 修正字段类型的命名空间
            field_type = self._fix_field_type_namespace(field.type_name, field.field_type)
            code += f"    {field_type} {field.name};{comment}\n"
        
        code += "};\n"
        
        return code
    
    def _get_field_comment(self, field: Field) -> str:
        """获取字段注释"""
        comments = []
        if field.is_required:
            comments.append("required")
        if field.is_key:
            comments.append("key")
        if field.default_value:
            comments.append(f"default: {field.default_value}")
            
        if comments:
            return f"  // {', '.join(comments)}"
        return ""
    
    def _get_default_initialization(self, field: Field) -> str:
        """获取字段的默认初始化值"""
        if field.default_value:
            if field.field_type == FieldType.STRING:
                value = field.default_value.strip('"\'')
                return f' = "{value}"'
            elif field.field_type == FieldType.BASIC:
                if field.type_name == 'bool':
                    return f" = {field.default_value.lower()}"
                else:
                    return f" = {field.default_value}"
            elif field.field_type == FieldType.ENUM:
                # 处理枚举类型的默认值，FlatBuffer生成的枚举值有前缀
                enum_type = field.type_name
                enum_value = field.default_value
                return f" = {enum_type}_{enum_value}"
            else:
                return f" = {field.default_value}"
        else:
            # POD类型的零初始化
            if field.field_type == FieldType.BASIC:
                if 'int' in field.type_name or 'float' in field.type_name or 'double' in field.type_name:
                    return " = 0"
                elif field.type_name == 'bool':
                    return " = false"
            return ""  # 字符串和向量使用默认构造
    
    def _generate_serialization_functions(self, struct_def: StructDef) -> str:
        """生成序列化函数"""
        
        # 过滤掉废弃的字段和Union字段（Union字段需要特殊处理，暂时跳过）
        # 同时也过滤掉包含Union元素的向量
        def should_skip_field(field):
            if field.is_deprecated:
                return True
            if field.field_type == FieldType.UNION:
                return True
            if field.field_type == FieldType.VECTOR and field.vector_element_type:
                # 检查向量元素是否为Union类型
                if field.vector_element_type in self.union_map:
                    return True
            return False
        
        active_fields = [f for f in struct_def.fields if not should_skip_field(f)]
        struct_name = f"{struct_def.name}Msg"
        
        # FlatBuffer 类型使用全局命名空间引用
        flatbuffer_namespace_prefix = f"::{self.schema.namespace}::" if self.schema.namespace else "::"
        # POD 结构体使用相对命名空间引用（在 flatbuffers 命名空间内）
        pod_namespace_prefix = f"{self.schema.namespace}::" if self.schema.namespace else ""
        
        code = f"""/**
 * @brief 序列化{struct_def.name}数据到FlatBuffer
 * @param builder FlatBuffer构建器
 * @param data 要序列化的数据
 * @return FlatBuffer offset
 */
template<>
flatbuffers::Offset<{flatbuffer_namespace_prefix}{struct_def.name}> serialize(flatbuffers::FlatBufferBuilder& builder, const {pod_namespace_prefix}{struct_name}& data) {{
"""
        
        # 生成字符串和向量的预处理
        string_offsets = []
        vector_offsets = []
        
        for field in active_fields:
            if field.field_type == FieldType.STRING:
                offset_name = f"{field.name}_offset"
                string_offsets.append(offset_name)
                code += f"    auto {offset_name} = builder.CreateString(data.{field.name});\n"
            elif field.field_type == FieldType.VECTOR:
                offset_name = f"{field.name}_offset"
                vector_offsets.append(offset_name)
                if field.vector_element_type == 'string':
                    code += f"    std::vector<flatbuffers::Offset<flatbuffers::String>> {field.name}_str_offsets;\n"
                    code += f"    for (const auto& item : data.{field.name}) {{\n"
                    code += f"        {field.name}_str_offsets.push_back(builder.CreateString(item));\n"
                    code += f"    }}\n"
                    code += f"    auto {offset_name} = builder.CreateVector({field.name}_str_offsets);\n"
                elif field.vector_element_type and field.vector_element_type in self.table_map:
                    # 处理Table类型的向量，需要先序列化每个元素
                    element_type = field.vector_element_type
                    code += f"    // 序列化{element_type}列表\n"
                    code += f"    std::vector<flatbuffers::Offset<{flatbuffer_namespace_prefix}{element_type}>> {field.name}_element_offsets;\n"
                    code += f"    {field.name}_element_offsets.reserve(data.{field.name}.size());\n"
                    code += f"    for (const auto& item : data.{field.name}) {{\n"
                    code += f"        {field.name}_element_offsets.push_back(flatbuffers::serialize<{flatbuffer_namespace_prefix}{element_type}>(builder, item));\n"
                    code += f"    }}\n"
                    code += f"    auto {offset_name} = builder.CreateVector({field.name}_element_offsets);\n"
                else:
                    code += f"    auto {offset_name} = builder.CreateVector(data.{field.name});\n"
        
        if string_offsets or vector_offsets:
            code += "\n"
        
        # 生成Create调用，需要处理所有字段包括Union字段
        code += f"    return {flatbuffer_namespace_prefix}Create{struct_def.name}(builder"
        
        # 遍历所有字段（包括Union字段），按原始顺序
        # 但是不能跳过Union向量字段，因为需要处理它们的序列化参数
        all_fields = [f for f in struct_def.fields if not f.is_deprecated]
        for field in all_fields:
            if field.field_type == FieldType.UNION:
                # Union字段传递默认值
                # Union字段的默认值是 NONE
                # 构造完整的命名空间路径
                namespace_prefix = f"::{self.schema.namespace}" if self.schema.namespace else ""
                # 去掉 type_name 中可能存在的前缀，只保留类型名
                clean_type_name = field.type_name.lstrip(":").split("::")[-1]
                union_value = f"{namespace_prefix}::{clean_type_name}_NONE"
                code += f", {union_value}"
                code += f", 0"  # Union数据的offset，传0表示空
            elif field.field_type == FieldType.STRING:
                code += f", {field.name}_offset"
            elif field.field_type == FieldType.VECTOR:
                # 检查是否为Union向量，如果是，传递默认值
                if field.vector_element_type and field.vector_element_type in self.union_map:
                    # Union向量字段传递空的uint8向量
                    code += f", builder.CreateVector(std::vector<uint8_t>())"
                else:
                    code += f", {field.name}_offset"
            elif field.field_type == FieldType.STRUCT:
                # FlatBuffer 结构体需要传递指针
                code += f", &data.{field.name}"
            elif field.field_type == FieldType.TABLE:
                # Table类型需要先序列化
                original_type = field.original_type_name or field.type_name
                code += f", serialize<{flatbuffer_namespace_prefix}{original_type}>(builder, data.{field.name})"
            else:
                code += f", data.{field.name}"
        
        code += ");\n}\n\n"
        
        # 生成反序列化函数
        code += f"""/**
 * @brief 从FlatBuffer反序列化{struct_def.name}数据
 * @param data 输出数据结构
 * @param fb_obj FlatBuffer对象指针
 * @return 是否成功
 */
template<>
bool deserialize({pod_namespace_prefix}{struct_name}& data, const {flatbuffer_namespace_prefix}{struct_def.name}* fb_obj) {{
    if (!fb_obj) {{
        return false;
    }}
    
"""
        
        for field in active_fields:
            if field.field_type == FieldType.STRING:
                code += f"    if (fb_obj->{field.name}()) {{\n"
                code += f"        data.{field.name} = fb_obj->{field.name}()->str();\n"
                code += f"    }}\n"
            elif field.field_type == FieldType.VECTOR:
                if field.vector_element_type == 'string':
                    code += f"    if (fb_obj->{field.name}()) {{\n"
                    code += f"        data.{field.name}.clear();\n"
                    code += f"        for (const auto* item : *fb_obj->{field.name}()) {{\n"
                    code += f"            if (item) {{\n"
                    code += f"                data.{field.name}.push_back(item->str());\n"
                    code += f"            }}\n"
                    code += f"        }}\n"
                    code += f"    }}\n"
                elif field.vector_element_type and field.vector_element_type in self.table_map:
                    # 处理Table类型的向量，需要反序列化每个元素
                    element_type = field.vector_element_type
                    code += f"    if (fb_obj->{field.name}()) {{\n"
                    code += f"        data.{field.name}.clear();\n"
                    code += f"        data.{field.name}.reserve(fb_obj->{field.name}()->size());\n"
                    code += f"        for (const auto* item : *fb_obj->{field.name}()) {{\n"
                    code += f"            data.{field.name}.push_back(from_flatbuffer<{pod_namespace_prefix}{element_type}Msg>(item));\n"
                    code += f"        }}\n"
                    code += f"    }}\n"
                else:
                    code += f"    if (fb_obj->{field.name}()) {{\n"
                    code += f"        data.{field.name}.assign(fb_obj->{field.name}()->begin(), fb_obj->{field.name}()->end());\n"
                    code += f"    }}\n"
            elif field.field_type == FieldType.STRUCT:
                # FlatBuffer 结构体返回指针，需要解引用
                code += f"    if (fb_obj->{field.name}()) {{\n"
                code += f"        data.{field.name} = *fb_obj->{field.name}();\n"
                code += f"    }}\n"
            elif field.field_type == FieldType.TABLE:
                # Table类型需要反序列化
                code += f"    if (fb_obj->{field.name}()) {{\n"
                code += f"        data.{field.name} = from_flatbuffer<{pod_namespace_prefix}{field.type_name}>(fb_obj->{field.name}());\n"
                code += f"    }}\n"
            else:
                code += f"    data.{field.name} = fb_obj->{field.name}();\n"
        
        code += """    
    return true;
}

"""
        
        # 生成便利函数
        code += f"""/**
 * @brief 从FlatBuffer创建{struct_def.name}数据（便利函数）
 * @param fb_obj FlatBuffer对象指针
 * @return 反序列化的数据对象
 */
template<>
{pod_namespace_prefix}{struct_name} from_flatbuffer(const {flatbuffer_namespace_prefix}{struct_def.name}* fb_obj) {{
    {pod_namespace_prefix}{struct_name} data;
    deserialize(data, fb_obj);
    return data;
}}"""
        
        return code
    


def main():
    parser = argparse.ArgumentParser(description='FlatBuffer Schema to C++ Struct Generator (V2版本)')
    parser.add_argument('input_file', help='输入的.fbs文件路径')
    parser.add_argument('output_file', help='输出的.h文件路径')
    parser.add_argument('--verbose', '-v', action='store_true', help='显示详细信息')
    
    args = parser.parse_args()
    
    if not os.path.exists(args.input_file):
        print(f"错误: 输入文件不存在: {args.input_file}")
        return 1
    
    try:
        # 解析schema
        parser = FlatBufferSchemaParser()
        schema = parser.parse_file(args.input_file)
        
        if args.verbose:
            print(f"解析schema: {args.input_file}")
            print(f"Namespace: {schema.namespace}")
            print(f"Enums: {len(schema.enums)}")
            print(f"Structs/Tables: {len(schema.structs)}")
            
            # 显示废弃字段统计
            for struct_def in schema.structs:
                if struct_def.is_table:
                    active_fields = [f for f in struct_def.fields if not f.is_deprecated]
                    deprecated_fields = [f for f in struct_def.fields if f.is_deprecated]
                    print(f"  {struct_def.name}: {len(active_fields)} 活跃字段, {len(deprecated_fields)} 废弃字段")
                    if deprecated_fields and args.verbose:
                        print(f"    废弃字段: {', '.join([f.name for f in deprecated_fields])}")
        
        # 生成C++代码
        generator = CppPodStructGenerator(schema)
        generator.generate_header(args.output_file)
        
        print(f"成功生成C++ POD结构体文件: {args.output_file}")
        
        return 0
        
    except Exception as e:
        print(f"错误: {e}")
        if args.verbose:
            import traceback
            traceback.print_exc()
        return 1

if __name__ == '__main__':
    sys.exit(main())
